/*------------------------------------------------------------------------------
 * Copyright 2012 NCR Corporation
 *------------------------------------------------------------------------------
 * All revision information is updated automatically from source code control
 * change records - please do not manually edit.
 *------------------------------------------------------------------------------
 *
 * $LastChangedRevision:: 2123                                     $
 * $LastChangedBy:: rb250096                                       $
 * $LastChangedDate:: 2012-04-18 00:43:25 -0400 (Wed, 18 Apr 2012) $
 */

package com.ncr.nep.dashboardcore.utils.client;


import com.google.gwt.core.client.JavaScriptObject;
import com.google.web.bindery.event.shared.Event;

/**
 * Event used to facilitate messaging between two {@link InterWindowEventBus}
 * instances in two different JavaScript windows (for instance, two different
 * iframes).
 *
 * @author rb250096
 * @version $Revision: 2123 $
 */
public class InterWindowEvent extends Event<InterWindowHandler> {

    //--------------------------------------------------------------------------
    //
    //  Fields
    //
    //--------------------------------------------------------------------------

    /**
     * The event type.
     */
    public static final Type<InterWindowHandler> TYPE =
            new Type<InterWindowHandler>();

    /**
     * Message type for an event that is dispatched when the instance of
     * {@link InterWindowEventBus} has registered with the master bus.
     */
    public static final String REGISTERED_EVENT_TYPE = "__registered__";

    /**
     * True to broadcast the event to all {@link InterWindowEventBus} instances.
     */
    protected boolean broadcast;

    /**
     * The type of message represented by the event.
     */
    protected String messageType;

    /**
     * The ID of the {@link InterWindowEventBus} that dispatched the event.
     */
    protected String sourceId;

    /**
     * The body of the message.  This is either a JSON string or a
     * {@link JavaScriptObject}.
     */
    protected Object body;

    //--------------------------------------------------------------------------
    //
    //  Constructors
    //
    //--------------------------------------------------------------------------

    /**
     * Constructor.
     *
     * @param messageType The type of message represented by this event.
     * @param body The body of the message.  This can be either a JSON string
     *             or a {@link JavaScriptObject}.
     * @param broadcast True to broadcast the message to all known
     *                  {@link InterWindowEventBus} instances.
     */
    public InterWindowEvent(String messageType,
                            Object body,
                            boolean broadcast) {
        if(!(body instanceof String) && !(body instanceof JavaScriptObject)) {
            throw new IllegalArgumentException("Body must be either a JSON " +
                    "string or a JavaScriptObject.");
        }

        this.messageType = messageType;
        this.body = body;
        this.broadcast = broadcast;
    }

    /**
     * Constructor.
     *
     * @param msg Message object that will be dispatched to other buses.
     * @param broadcast True to broadcast to all known
     * {@link InterWindowEventBus} instances, false to only dispatch to parent.
     */
    public InterWindowEvent(InterWindowMessage msg, boolean broadcast) {
        this(msg.getMessageType(), msg, broadcast);
    }

    /**
     * Constructor used for generating events from messages received from
     * another bus.
     *
     * @param messageType The type of message.
     * @param sourceId The ID of the source of the message.
     * @param body The body of the message.
     */
    protected InterWindowEvent(String messageType,
                               String sourceId,
                               Object body) {
        this.messageType = messageType;
        this.sourceId = sourceId;
        this.body = body;
    }

    //--------------------------------------------------------------------------
    //
    //  Properties
    //
    //--------------------------------------------------------------------------

    @Override
    public Type<InterWindowHandler> getAssociatedType() {
        return TYPE;
    }

    /**
     * Gets the type of message represented by this event.
     *
     * @return The message type.
     */
    public String getMessageType() {
        return messageType;
    }

    /**
     * Gets boolean indicating if event/message will be broadcast to all
     * other known {@link InterWindowEventBus} instances.
     *
     * @return True if the message will be broadcast.
     */
    public boolean isBroadcast() {
        return this.broadcast;
    }

    /**
     * Gets the body of the message.  This will be either a JSON string or a
     * {@link JavaScriptObject}.
     *
     * @return The body of the message encapsulated by this event.
     */
    public Object getBody() {
        return this.body;
    }

    //--------------------------------------------------------------------------
    //
    //  Methods
    //
    //--------------------------------------------------------------------------

    @Override
    protected void dispatch(InterWindowHandler handler) {
        handler.onEventReceived(this);
    }
}
